<template>
  <div 
    class="notification-bell" 
    :class="{ dragging: isDragging }"
    @mousedown="handleMouseDown"
    :style="{ top: position.y + 'px', right: position.x + 'px' }"
  >
    <div class="bell-icon">
      <svg width="20" height="20" viewBox="0 0 1024 1024" fill="currentColor">
        <path d="M512 64c-181.066 0-328 146.934-328 328v200.32L87.573 680.747a32 32 0 0 0 22.627 54.587h803.6a32 32 0 0 0 22.627-54.587L840 592.32V392c0-181.066-146.934-328-328-328zM248 392c0-145.728 118.272-264 264-264s264 118.272 264 264v180.821l64 64H184l64-64V392z"/>
        <path d="M384 800c0 70.692 57.308 128 128 128s128-57.308 128-128H384z"/>
      </svg>
      <div v-if="unreadCount > 0" class="notification-badge">
        {{ unreadCount > 99 ? '99+' : unreadCount }}
      </div>
    </div>
    
    <!-- 通知面板 -->
    <div v-if="showPanel" class="notification-panel" @click.stop @mousedown.stop :style="panelPosition">
      <div class="panel-header">
        <h3>消息通知</h3>
        <button class="close-btn" @click="showPanel = false">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
            <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
          </svg>
        </button>
      </div>
      
      <!-- 标签页 -->
      <div class="panel-tabs">
        <div 
          class="tab-item" 
          :class="{ active: activeTab === 'all' }"
          @click="activeTab = 'all'"
        >
          全部 ({{ allNotifications.length }})
        </div>
        <div 
          class="tab-item" 
          :class="{ active: activeTab === 'unread' }"
          @click="activeTab = 'unread'"
        >
          未读 ({{ unreadNotifications.length }})
        </div>
        <div 
          class="tab-item" 
          :class="{ active: activeTab === 'read' }"
          @click="activeTab = 'read'"
        >
          已读 ({{ readNotifications.length }})
        </div>
      </div>
      
      <!-- 通知列表 -->
      <div class="notification-list">
        <div v-if="currentNotifications.length === 0" class="empty-state">
          <svg width="48" height="48" viewBox="0 0 1024 1024" fill="#d1d5db">
            <path d="M512 64c-181.066 0-328 146.934-328 328v200.32L87.573 680.747a32 32 0 0 0 22.627 54.587h803.6a32 32 0 0 0 22.627-54.587L840 592.32V392c0-181.066-146.934-328-328-328z"/>
            <path d="M384 800c0 70.692 57.308 128 128 128s128-57.308 128-128H384z"/>
          </svg>
          <p>暂无通知消息</p>
        </div>
        
        <div 
          v-for="notification in currentNotifications" 
          :key="notification.id"
          class="notification-item"
          :class="{ unread: !notification.isRead }"
          @click="handleNotificationClick(notification)"
        >
          <div class="notification-content">
            <div class="notification-title">{{ notification.title }}</div>
            <div class="notification-message">{{ notification.message }}</div>
            <div class="notification-time">{{ formatTime(notification.time) }}</div>
          </div>
          <div v-if="!notification.isRead" class="unread-dot"></div>
        </div>
      </div>
      
      <!-- 操作按钮 -->
      <div class="panel-footer">
        <button 
          v-if="unreadNotifications.length > 0" 
          class="mark-all-read-btn"
          @click="markAllAsRead"
        >
          全部标记为已读
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'

interface Notification {
  id: string
  title: string
  message: string
  time: number
  isRead: boolean
  type?: 'info' | 'warning' | 'error' | 'success'
}

const showPanel = ref(false)
const activeTab = ref<'all' | 'unread' | 'read'>('all')

// 拖拽相关状态
const position = ref({ x: 20, y: window.innerHeight / 2 - 24 }) // 默认居中位置
const isDragging = ref(false)
const dragOffset = ref({ x: 0, y: 0 })

// 模拟通知数据
const notifications = ref<Notification[]>([
  {
    id: '1',
    title: '系统通知',
    message: '您有新的工作任务需要处理',
    time: Date.now() - 1000 * 60 * 30, // 30分钟前
    isRead: false,
    type: 'info'
  },
  {
    id: '2',
    title: '文档审核',
    message: '您提交的文档已通过审核',
    time: Date.now() - 1000 * 60 * 60 * 2, // 2小时前
    isRead: false,
    type: 'success'
  },
  {
    id: '3',
    title: '会议提醒',
    message: '您有一个会议将在15分钟后开始',
    time: Date.now() - 1000 * 60 * 60 * 24, // 1天前
    isRead: true,
    type: 'warning'
  },
  {
    id: '4',
    title: '权限变更',
    message: '您的账户权限已更新',
    time: Date.now() - 1000 * 60 * 60 * 24 * 2, // 2天前
    isRead: true,
    type: 'info'
  }
])

// 计算属性
const allNotifications = computed(() => notifications.value)
const unreadNotifications = computed(() => notifications.value.filter(n => !n.isRead))
const readNotifications = computed(() => notifications.value.filter(n => n.isRead))
const unreadCount = computed(() => unreadNotifications.value.length)

const currentNotifications = computed(() => {
  switch (activeTab.value) {
    case 'unread':
      return unreadNotifications.value
    case 'read':
      return readNotifications.value
    default:
      return allNotifications.value
  }
})

// 计算通知面板位置
const panelPosition = computed(() => {
  const panelWidth = 360
  const spacing = 16
  
  // 计算按钮在屏幕上的实际left位置
  const buttonLeft = window.innerWidth - position.value.x - 48
  
  // 如果按钮在屏幕右半部分，面板显示在左侧
  const showOnLeft = buttonLeft > window.innerWidth / 2
  
  if (showOnLeft) {
    // 显示在按钮左侧
    return {
      top: Math.max(spacing, position.value.y - 200) + 'px',
      right: (position.value.x + 60) + 'px',
      left: 'auto'
    }
  } else {
    // 显示在按钮右侧
    return {
      top: Math.max(spacing, position.value.y - 200) + 'px',
      left: (buttonLeft + 60) + 'px',
      right: 'auto'
    }
  }
})

// 方法
function handleBellClick() {
  showPanel.value = !showPanel.value
}

// 拖拽相关方法
function handleMouseDown(event: MouseEvent) {
  const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
  dragOffset.value = {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top
  }
  
  // 记录开始位置，用于判断是否真的在拖拽
  const startPosition = { x: event.clientX, y: event.clientY }
  let hasMoved = false
  
  const handleMouseMove = (moveEvent: MouseEvent) => {
    const deltaX = Math.abs(moveEvent.clientX - startPosition.x)
    const deltaY = Math.abs(moveEvent.clientY - startPosition.y)
    
    // 只有移动超过5像素才认为是拖拽
    if (deltaX > 5 || deltaY > 5) {
      hasMoved = true
      isDragging.value = true
      
      // 计算新位置（以按钮左上角为基准）
      const newLeft = moveEvent.clientX - dragOffset.value.x
      const newTop = moveEvent.clientY - dragOffset.value.y
      
      // 边界限制
      const minLeft = 0
      const maxLeft = window.innerWidth - 48
      const minTop = 0
      const maxTop = window.innerHeight - 48
      
      const constrainedLeft = Math.max(minLeft, Math.min(maxLeft, newLeft))
      const constrainedTop = Math.max(minTop, Math.min(maxTop, newTop))
      
      // 转换为 right 和 top 坐标
      position.value.x = window.innerWidth - constrainedLeft - 48
      position.value.y = constrainedTop
    }
  }
  
  const handleMouseUp = () => {
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
    
    // 如果没有移动，触发点击事件
    if (!hasMoved) {
      handleBellClick()
    }
    
    // 重置拖拽状态
    setTimeout(() => {
      isDragging.value = false
    }, 100)
  }
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

function handleNotificationClick(notification: Notification) {
  if (!notification.isRead) {
    notification.isRead = true
  }
  // 这里可以添加跳转到详情页面的逻辑
  console.log('点击通知:', notification)
}

function markAllAsRead() {
  notifications.value.forEach(notification => {
    notification.isRead = true
  })
}

function formatTime(timestamp: number) {
  const now = Date.now()
  const diff = now - timestamp
  
  const minute = 1000 * 60
  const hour = minute * 60
  const day = hour * 24
  
  if (diff < minute) {
    return '刚刚'
  } else if (diff < hour) {
    return `${Math.floor(diff / minute)}分钟前`
  } else if (diff < day) {
    return `${Math.floor(diff / hour)}小时前`
  } else {
    return `${Math.floor(diff / day)}天前`
  }
}

// 点击外部关闭面板
function handleClickOutside(event: Event) {
  const target = event.target as HTMLElement
  // 确保点击的不是通知铃铛组件内的任何元素
  if (!target.closest('.notification-bell') && !target.closest('.notification-panel')) {
    showPanel.value = false
  }
}

onMounted(() => {
  document.addEventListener('click', handleClickOutside)
  
  // 监听窗口大小变化，调整位置
  const handleResize = () => {
    const maxX = window.innerWidth - 48
    const maxY = window.innerHeight - 48
    
    // 确保按钮不会超出新的窗口边界
    const currentLeft = window.innerWidth - position.value.x - 48
    const currentTop = position.value.y
    
    const constrainedLeft = Math.max(0, Math.min(maxX, currentLeft))
    const constrainedTop = Math.max(0, Math.min(maxY, currentTop))
    
    position.value.x = window.innerWidth - constrainedLeft - 48
    position.value.y = constrainedTop
  }
  
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
})
</script>

<style scoped>
.notification-bell {
  position: fixed;
  z-index: 9999;
  cursor: move;
  user-select: none;
}

.bell-icon {
  position: relative;
  width: 48px;
  height: 48px;
  cursor: pointer;
  color: white;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 50%;
  background: linear-gradient(135deg, #5b7cff 0%, #a685ff 100%);
  box-shadow: 0 4px 20px rgba(91, 124, 255, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(255, 255, 255, 0.9);
}



.bell-icon:hover {
  background: linear-gradient(135deg, #4c63d2 0%, #8b5cf6 100%);
  transform: translateY(-2px) scale(1.1);
  box-shadow: 0 8px 30px rgba(91, 124, 255, 0.4);
}

.notification-bell:active .bell-icon {
  transform: scale(0.95);
}

.notification-bell.dragging {
  cursor: grabbing !important;
}

.notification-bell.dragging .bell-icon {
  transform: scale(1.05);
  box-shadow: 0 8px 30px rgba(91, 124, 255, 0.5);
}

.notification-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  background: linear-gradient(135deg, #ff4757 0%, #ff3742 100%);
  color: white;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 12px;
  min-width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 3px white, 0 2px 12px rgba(255, 71, 87, 0.5);
  animation: pulse 2s infinite;
  pointer-events: none;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.9;
  }
}

.notification-panel {
  position: fixed;
  width: 360px;
  height: 480px;
  background: rgba(255, 255, 255, 0.98);
  backdrop-filter: blur(20px);
  border-radius: 16px;
  box-shadow: 
    0 24px 48px rgba(0, 0, 0, 0.12),
    0 8px 24px rgba(0, 0, 0, 0.08),
    0 0 0 1px rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.08);
  z-index: 10000;
  overflow: hidden;
  animation: slideIn 0.2s ease-out;
  display: flex;
  flex-direction: column;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(-10px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  background: linear-gradient(135deg, rgba(248, 250, 255, 0.8) 0%, rgba(224, 231, 255, 0.6) 100%);
  border-radius: 16px 16px 0 0;
  backdrop-filter: blur(10px);
}

.panel-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #374151;
}

.close-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #6b7280;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}



.close-btn:hover {
  background: #f3f4f6;
  color: #374151;
}

.panel-tabs {
  display: flex;
  border-bottom: 1px solid #f3f4f6;
}

.tab-item {
  flex: 1;
  padding: 12px 16px;
  text-align: center;
  cursor: pointer;
  font-size: 14px;
  color: #6b7280;
  transition: all 0.2s ease;
  border-bottom: 2px solid transparent;
}

.tab-item:hover {
  background: #f9fafb;
  color: #374151;
}

.tab-item.active {
  color: #5b7cff;
  border-bottom-color: #5b7cff;
  background: #f8faff;
  font-weight: 500;
}

.notification-list {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  color: #9ca3af;
}

.empty-state svg {
  margin-bottom: 12px;
}

.empty-state p {
  margin: 8px 0 0 0;
  font-size: 14px;
}

.notification-item {
  display: flex;
  align-items: flex-start;
  padding: 18px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.04);
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  backdrop-filter: blur(10px);
}

.notification-item:hover {
  background: rgba(91, 124, 255, 0.04);
  transform: translateX(2px);
}

.notification-item:last-child {
  border-bottom: none;
}

.notification-item.unread {
  background: linear-gradient(135deg, rgba(254, 254, 254, 0.8) 0%, rgba(248, 250, 255, 0.6) 100%);
  border-left: 3px solid #5b7cff;
  padding-left: 21px;
}

.notification-content {
  flex: 1;
  min-width: 0;
}

.notification-title {
  font-weight: 600;
  font-size: 14px;
  color: #374151;
  margin-bottom: 4px;
}

.notification-message {
  font-size: 13px;
  color: #6b7280;
  line-height: 1.4;
  margin-bottom: 6px;
  word-break: break-word;
  overflow-wrap: break-word;
  white-space: pre-wrap;
}

.notification-time {
  font-size: 12px;
  color: #9ca3af;
}

.unread-dot {
  width: 8px;
  height: 8px;
  background: #5b7cff;
  border-radius: 50%;
  margin-left: 12px;
  margin-top: 6px;
  flex-shrink: 0;
}

.panel-footer {
  padding: 16px 24px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
  background: linear-gradient(135deg, rgba(250, 251, 252, 0.8) 0%, rgba(248, 250, 255, 0.6) 100%);
  border-radius: 0 0 16px 16px;
  backdrop-filter: blur(10px);
}

.mark-all-read-btn {
  width: 100%;
  padding: 8px 16px;
  background: linear-gradient(135deg, #5b7cff 0%, #a685ff 100%);
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.mark-all-read-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(91, 124, 255, 0.3);
}

/* 滚动条样式 */
.notification-list::-webkit-scrollbar {
  width: 6px;
}

.notification-list::-webkit-scrollbar-track {
  background: transparent;
}

.notification-list::-webkit-scrollbar-thumb {
  background: rgba(203, 213, 225, 0.5);
  border-radius: 3px;
  transition: background-color 0.2s ease;
}

.notification-list::-webkit-scrollbar-thumb:hover {
  background: rgba(148, 163, 184, 0.8);
}

/* 避免水平滚动条出现 */
.notification-list::-webkit-scrollbar-horizontal {
  display: none;
}
</style>
